package com.zb.tools;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Calendar.Builder;
import java.util.Date;
import java.util.List;


public class StringKit
{
	static public final String[] emptyStrArray=new String[0];
	static public final String Empty="";
	static public final char split_chars[]={'|',',',':',';','/','\\'};
	
	//比较两个字符串，都为空时返回真
	static public boolean notEqual(String a,String b)
	{
		if(a==b) return false;
		if(a==null||b==null) return true;
		return !a.equals(b);		
	}
	
	/***
	 * 根据字符'|',',',':',';','/','\\'，将输入字串拆分成多个字符串（带trim）
	 * @param str 输入的字符串
	 * @return 拆分后的字符串列表
	 */	
	static public String[] split(String str)
	{
		return split(str,split_chars);
	}
	
	/***
	 * 根据字符列表的字符，将输入字串拆分成多个字符串（带trim）
	 * @param str 输入的字符串
	 * @param c 拆分字符
	 * @return 拆分后的字符串列表
	 */	
	static public String[] split(String str,char c)
	{
		if(str==null)
			return null;
		int count=1,len=str.length();
		for(int i=0;i<len;i++)
		{
			if(str.charAt(i)==c)
				count++;
		}
		String[] ret=new String[count];
		int l=0,j=0;
		for(int i=0;i<len;i++)
		{
			if(str.charAt(i)==c)
			{
				ret[j++]=str.substring(l,i).trim();
				l=i+1;
			}
		}
		if(j<ret.length)
			ret[j]=str.substring(l,len).trim();
		return ret;
	}

	
	/***
	 * 根据字符列表的字符，将输入字串拆分成多个字符串（双引号内识别为一个，带trim）
	 * @param str 输入的字符串
	 * @param c 拆分字符
	 * @return 拆分后的字符串列表
	 */	
	static public String[] splitEx(String str,char c)
	{
		if(str==null)
			return null;
		int count=1,len=str.length();
		boolean out=true;
		for(int i=0;i<len;i++)
		{
			char cc=str.charAt(i);
			if(cc=='"')
				out=!out;
			else if(out&&cc==c)
				count++;
		}
		String[] ret=new String[count];
		int l=0,j=0;
		out=true;
		for(int i=0;i<len;i++)
		{
			char cc=str.charAt(i);
			if(cc=='"')
				out=!out;
			else if(out&&cc==c)
			{
				String s=str.substring(l,i);
				int size=s.length();
				if(size>=2&&s.charAt(0)=='"'&&s.charAt(size-1)=='"') //两边是引号
					ret[j++]=s.substring(1,size-1);
				else if(size>=2&&s.charAt(0)=='\''&&s.charAt(size-1)=='\'') //两边是单引号
					ret[j++]=s.substring(1,size-1);
				else
					ret[j++]=s.trim();
				l=i+1;
			}
		}
		if(j<ret.length)
		{
			String s=str.substring(l,len);
			int size=s.length();
			if(size>=2&&s.charAt(0)=='"'&&s.charAt(size-1)=='"') //两边是引号
				ret[j]=s.substring(1,size-1);
			else if(size>=2&&s.charAt(0)=='\''&&s.charAt(size-1)=='\'') //两边是单引号
				ret[j]=s.substring(1,size-1);
			else
				ret[j]=s.trim();
		}
		return ret;
	}
	
	/***
	 * 根据字符列表的字符，将输入字串拆分成多个字符串（带trim）
	 * @param str 输入的字符串
	 * @param cs 拆分字符列表
	 * @return 拆分后的字符串列表
	 */
	static public String[] split(String str,char ...cs)
	{
		if(str==null)
			return emptyStrArray;
		int count=1,len=str.length();
		for(int i=0;i<len;i++)
		{
			for(char c:cs)
				if(str.charAt(i)==c)
				{
					count++;
					break;
				}
		}
		String[] ret=new String[count];
		int l=0,j=0;
		for(int i=0;i<len;i++)
		{
			for(char c:cs)
			if(str.charAt(i)==c)
			{
				ret[j++]=str.substring(l,i).trim();
				l=i+1;
				break;
			}
		}
		if(j<ret.length)
			ret[j]=str.substring(l,len).trim();
		return ret;
	}
	
	static public String join(char spliter,String...strs)
	{
		StringBuilder sb=new StringBuilder();
		for(int i=0;i<strs.length;i++)
		{
			if(i>0) sb.append(spliter);
			sb.append(strs[i]);
		}
		return sb.toString();
	}

	public static byte[] readStream(InputStream is) throws IOException
	{

		ByteBuffer buffer=ByteBuffer.allocate(4096);
		int c=is.read();
		while(c!=-1)
		{
			if(buffer.remaining()>0)
			{
				ByteBuffer buffer2=ByteBuffer.allocate(buffer.capacity()+4096);
				buffer2.put(buffer);
				buffer=buffer2;
			}
			buffer.put((byte)c);
			c=is.read();
		}
		is.close();
		byte[] data=new byte[buffer.position()];
		buffer.get(data);
		return data;
	}
	
	/***
	 * 将指定文件(可以是文件，也可以是资源)以指定编码读取到字符串
	 */
	static public String readFile(String filename,Charset charset)
	{
		try
		{
			File file=new File(filename);
			InputStream is;
			if(!file.exists()) //文件路径没有，就从资源中查找
			{
				ClassLoader loader=Thread.currentThread().getContextClassLoader();
				//ClassLoader loader=ClassLoader.getSystemClassLoader();
				//ClassLoader loader=StringKit.class.getClassLoader();
				is=loader.getResourceAsStream(filename);
			}
			else
			{
				is=new FileInputStream(file);
			}
			if(is==null) return "";
			InputStreamReader isr=new InputStreamReader(is,charset);
			
			StringBuilder sb=new StringBuilder();
			int c=isr.read();
			if(c==0xFEFF) //Windows text BOM
				c=isr.read();
			else
				sb.append((char)c);
			char[] buffer=new char[2048];
			c=isr.read(buffer);
			while(c!=-1)
			{
				sb.append(buffer,0,c);
				c=isr.read(buffer);
			}
			isr.close();
			return sb.toString();
		}
		catch (Exception e)
		{
			e.printStackTrace();
			return ""; 
		}		
	}
	
	static public String readFile(String filename)
	{
		return readFile(filename,Charset.defaultCharset());
	}
	
	static public String readFile(String filename,String charset_name)
	{
		return readFile(filename,Charset.forName(charset_name));
	}
	
	/***
	 * 将unicode字符串以以指定编码写入到文件
	 */
	public static boolean saveFile(String filename,String content,Charset charset)
	{
		try
		{
			File file=new File(filename);
			byte[] data=content.getBytes(charset);
			FileOutputStream fw=new FileOutputStream(file);
			fw.write(data);
			fw.close();
			return true;
		}
		catch (Exception e)
		{
			e.printStackTrace();
			return false; 
		}		
	}
	
	public static boolean saveFile(String filename,String content,String charset)
	{
		return saveFile(filename,content,Charset.forName(charset));
	}

	/***
	 * 将指定文件(可以是文件，也可以是资源)以指定编码读取到字符串列表，以换行符间隔
	 */
	public static boolean saveFile(String filename,String content)
	{
		return saveFile(filename,content,Charset.defaultCharset());
	}
	
	
	/***
	 * 将指定文件(可以是文件，也可以是资源)以指定编码读取到字符串列表，以换行符间隔
	 */
	public static List<String> readAllLines(String filename,Charset charset)
	{
		try
		{
			
			File file=new File(filename);
			InputStream is;
			if(!file.exists()) //文件路径没有，就从资源中查找
			{
				ClassLoader loader=Thread.currentThread().getContextClassLoader();
				//ClassLoader loader=ClassLoader.getSystemClassLoader();
				//ClassLoader loader=StringKit.class.getClassLoader();
				is=loader.getResourceAsStream(filename);
			}
			else
				is=new FileInputStream(file);
			if(is==null) return null;
			BufferedReader br=new BufferedReader(new InputStreamReader(is,charset));
			List<String> lines=new ArrayList<String>();
			String line=br.readLine();
			if(line!=null&&line.length()>0&&line.charAt(0)==0xFEFF)  //Windows text BOM
				line=line.substring(1);
			while(line!=null)
			{
				lines.add(line);
				line=br.readLine();
			}
			br.close();
			return lines;
		}
		catch (Exception e)
		{
			e.printStackTrace();
			return null; 
		}
		
	}
	
	/***
	 * 从文件中读取所有行，指定字符集
	 */
	public static List<String> readAllLines(String filename,String charset)
	{
		return readAllLines(filename,Charset.forName(charset));
	}
	
	/***
	 * 从文件中读取所有行，使用jvm缺省字符集
	 */
	public static List<String> readAllLines(String filename)
	{
		return readAllLines(filename,Charset.defaultCharset());
	}
	
	/***
	 * 把多个字符串拼接成url（以/间隔,会把\修改为/并去掉末尾的/,因为windows和linux路径都支持/，所以也可以用来拼合路径）
	 */
	public static String makeUrl(String ...strs)
	{
		StringBuilder sb=new StringBuilder();
		sb.append(strs[0]);
		for(int i=1;i<strs.length;i++)
		{
			char c=sb.charAt(sb.length()-1);
			if(c=='\\') 
				sb.setCharAt(sb.length()-1,'/');
			else if(c!='/') 
				sb.append('/');
			c=strs[i].charAt(0);
			if(c=='\\'||c=='/')
				sb.append(strs[i].substring(1));
			else
				sb.append(strs[i]);
		}
		char c=sb.charAt(sb.length()-1);
		if(c=='\\'||c=='/')
			sb.deleteCharAt(sb.length()-1);
		return sb.toString();
	}
	
	/***
	 * 把字符串数组转成长整数数组，如果转换失败，用default_value值替代，如果输入为null，返回null
	 */
	public static long[] toLongArray(String[] strs,long default_value)
	{
		if(strs!=null)
		{
			long[] ret=new long[strs.length];
			for(int i=0;i<strs.length;i++)
			{
				try
				{
					ret[i]=Long.parseLong(strs[i]);
				}
				catch(Exception e)
				{
					ret[i]=default_value;
				}
			}
			return ret;
		}
		return null;
	}
	
	/***
	 * 把字符串数组转成整数数组，如果转换失败，用default_value值替代，如果输入为null，返回null
	 */
	public static int[] toLongArray(String[] strs,int default_value)
	{
		if(strs!=null)
		{
			int[] ret=new int[strs.length];
			for(int i=0;i<strs.length;i++)
			{
				try
				{
					ret[i]=Integer.parseInt(strs[i]);
				}
				catch(Exception e)
				{
					ret[i]=default_value;
				}
			}
			return ret;
		}
		return null;
	}
	
	/***
	 * 把字符串数组转成长整数对象数组，如果输入为null，返回null
	 */
	public static Long[] toLongArray(String[] strs)
	{
		if(strs!=null)
		{
			Long[] ret=new Long[strs.length];
			for(int i=0;i<strs.length;i++)
			{
				try
				{
					ret[i]=Long.valueOf(strs[i]);
				}
				catch(Exception e)
				{
					ret[i]=null;
				}
			}
			return ret;
		}
		return null;
	}
	
	/***
	 * 把字符串数组转成整数对象数组，如果输入为null，返回null
	 */
	public static Integer[] toIntArray(String[] strs)
	{
		if(strs!=null)
		{
			Integer[] ret=new Integer[strs.length];
			for(int i=0;i<strs.length;i++)
			{
				try
				{
					ret[i]=Integer.valueOf(strs[i]);
				}
				catch(Exception e)
				{
					ret[i]=null;
				}
			}
			return ret;
		}
		return null;
	}
	
	/***
	 * 把指定间隔字符的字符串，转变成int数组，如果输入为null，返回null
	 */
	static public Integer[] splitIntArray(String str,char c)
	{
		if(str==null) return null;
		String[] strs=split(str,c);
		return toIntArray(strs);
	}
	
	/***
	 * 把指定间隔字符的字符串，转变成long数组，如果输入为null，返回null
	 */
	static public Long[] splitLongArray(String str,char c)
	{
		if(str==null) return null;
		String[] strs=split(str,c);
		return toLongArray(strs);
	}
	
	/***
	 * 把指定间隔字符的字符串，转变成long数组，如果输入为null，返回null
	 */
	static public Date[] splitDateArray(String str,char c)
	{
		if(str==null) return null;
		String[] strs=split(str,c);
		Date[] dates=new Date[strs.length];
		for(int i=0;i<strs.length;i++)
			dates[i]=parseDate(strs[i],null);
		return dates;
	}
	
	
	public static final char[] hexChar={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
	public static final char[] hexCharU={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
	
	/***
	 * 把字节数组转成小写十六进制字符串
	 */
	public static String BytesToString(byte[] data)
	{
		if(data==null) return Empty;
		char[] buf=new char[data.length*2];
		for(int i=0,k=0;i<data.length;i++)
		{
			int c=data[i]&0xff;  //保险
			buf[k++]=hexChar[c>>4];
			buf[k++]=hexChar[c&15];
		}
		return new String(buf);
	}
	
	/***
	 * 把字节数组转成大写十六进制字符串
	 */
	public static String BytesToStringUpper(byte[] data)
	{
		if(data==null) return Empty;
		char[] buf=new char[data.length*2];
		for(int i=0,k=0;i<data.length;i++)
		{
			int c=data[i]&0xff;  //保险
			buf[k++]=hexCharU[c>>4];
			buf[k++]=hexCharU[c&15];
		}
		return new String(buf);
	}
	
	/***
	 * 把字符串中的十六进制字符串转换成字节数组(大小写都可以)
	 */
	public static byte[] StringToByte(String str)
	{
		byte[] data=new byte[str.length()/2];
		for(int i=0;i+1<str.length();i+=2)
		{
			int c=str.charAt(i);
			if(c>='0'&&c<='9') c=(c-'0');
			else if(c>='a'&&c<='f') c=(c-'a'+10);
			else if(c>='A'&&c<='F') c=(c-'A'+10);
			else
				throw new RuntimeException(str+" is not a hex number string!");
			int v=c<<4;
			c=c<<4;
			c=str.charAt(i+1);
			if(c>='0'&&c<='9') c=(c-'0');
			else if(c>='a'&&c<='f') c=(c-'a'+10);
			else if(c>='A'&&c<='F') c=(c-'A'+10);
			else
				throw new RuntimeException(str+" is not a hex number string!");
			data[i/2]=(byte) (v+c);
		}
		return data;
	}
	
	/***
	 * 将输入的大于号小于号替换成左右括号
	 */
	public static String replaceLgAndSm(String html)
	{
		if(html==null) return html;
		char[] array=html.toCharArray();
		boolean outer=true;
		for(int i=0;i<array.length;i++)
		{
			if(array[i]=='"') 
				outer=!outer;
			else if(outer)
			{
				if(array[i]=='<') array[i]='(';
				else if(array[i]=='>') array[i]=')';
			}
		}
		return new String(array);
	}
	
	/*
	 * 把字符串转成日期格式
	 */
	public static Date parseDateOld(String str,Date defaultValue)
	{
		try
		{
			int len=str.length();
			Builder builder=new Builder();
			if(len>=10)
			{
				int year=Integer.parseInt(str.substring(0,4));
				int month=Integer.parseInt(str.substring(5,7))-1;
				int day=Integer.parseInt(str.substring(8,10));
				builder.setDate(year,month,day);
			}
			else
				return defaultValue;
			if(len>=13)
			{
				int minute=0,second=0;
				int hour=Integer.parseInt(str.substring(11,13));
				if(len>=16)
					minute=Integer.parseInt(str.substring(14,16));
				if(len>=18)
					second=Integer.parseInt(str.substring(17));
				builder.setTimeOfDay(hour,minute,second);
			}
			return builder.build().getTime();
		}
		catch(Exception e)
		{
			return defaultValue;
		}
	}
	
	/*
	 * 把字符串转成日期格式，兼容年月日时分秒的和1位或2位数字
	 */
	public static Date parseDate(String str,Date defaultValue)
	{
		try
		{
			if(str==null) return defaultValue;
			int len=str.length();
			if(len==0) return defaultValue;
			int i=0;
			int year=0;
			for(;i<len;i++)
			{
				int c=str.charAt(i);
				if(c>='0'&&c<='9') year=year*10+(c-'0');
				else break;
			}
			for(;i<len;i++)
			{
				int c=str.charAt(i);
				if(c>='0'&&c<='9') break; 
			}
			int month=0;
			for(;i<len;i++)
			{
				int c=str.charAt(i);
				if(c>='0'&&c<='9') month=month*10+(c-'0');
				else break;
			}

 			for(;i<len;i++)
			{
				int c=str.charAt(i);
				if(c>='0'&&c<='9') break; 
			}
			int day=0;
			for(;i<len;i++)
			{
				int c=str.charAt(i);
				if(c>='0'&&c<='9') day=day*10+(c-'0');
				else break;
			}
			for(;i<len;i++)
			{
				int c=str.charAt(i);
				if(c>='0'&&c<='9') break; 
			}
			int hour=0;
			for(;i<len;i++)
			{
				int c=str.charAt(i);
				if(c>='0'&&c<='9') hour=hour*10+(c-'0');
				else break;
			}
			for(;i<len;i++)
			{
				int c=str.charAt(i);
				if(c>='0'&&c<='9') break; 
			}
			int minute=0;
			for(;i<len;i++)
			{
				int c=str.charAt(i);
				if(c>='0'&&c<='9') minute=minute*10+(c-'0');
				else break;
			}
			for(;i<len;i++)
			{
				int c=str.charAt(i);
				if(c>='0'&&c<='9') break; 
			}
			int second=0;
			for(;i<len;i++)
			{
				int c=str.charAt(i);
				if(c>='0'&&c<='9') second=second*10+(c-'0');
				else break;
			}
			
			Builder builder=new Builder();
			builder.setDate(year,month-1,day);
			builder.setTimeOfDay(hour,minute,second);
			return builder.build().getTime();
		}
		catch(Exception e)
		{
			return defaultValue;
		}
	}
	
	static public int parseInt(String str,int default_value)
	{
		try
		{
			return Integer.parseInt(str);
		}
		catch(NumberFormatException e)
		{
			return default_value;
		}
	}
	
	static public long parseLong(String str,long default_value)
	{
		try
		{
			return Long.parseLong(str);
		}
		catch(NumberFormatException e)
		{
			return default_value;
		}
	}
	
	static public double parseDouble(String str,double default_value)
	{
		try
		{
			return Double.parseDouble(str);
		}
		catch(NumberFormatException e)
		{
			return default_value;
		}
	}
	
	static public Integer valueOfInteger(String str)
	{
		try
		{
			return Integer.valueOf(str);
		}
		catch(NumberFormatException e)
		{
			return null;
		}
	}
	
	static public Long valueOfLong(String str)
	{
		try
		{
			return Long.valueOf(str);
		}
		catch(NumberFormatException e)
		{
			return null;
		}
	}

	static public Double valueOfDouble(String str)
	{
		try
		{
			return Double.valueOf(str);
		}
		catch(NumberFormatException e)
		{
			return null;
		}
	}
	
	static public BigDecimal parseDecimal(String str)
	{
		try
		{
			if(str.charAt(0)=='￥')
				str=str.substring(1);
			str=str.replace(",","");
			return new BigDecimal(str);
		}
		catch(NumberFormatException e)
		{
			return null;
		}
	}

}
